package BusinessLogic;

import BusinessLogic.Exceptions.DataAlreadyExistException;
import Domain.Movie;
import Domain.SearchMovieMethods;
import Domain.Actor;
import Domain.Exceptions.NoActorsException;
import Domain.Exceptions.NoGenresException;
import Domain.MySqlAccessors.MySqlMovieProxy;
import Domain.MySqlAccessors.MySqlGenreProxy;
import Domain.MySqlAccessors.MySqlActorProxy;
import org.apache.log4j.Logger;

import java.io.Serializable;
import java.util.*;

import Persistance.MySqlUtilityManagment;

public class MovieHandler implements IHandlers<Movie>, Serializable {

    static Logger logger            = Logger.getLogger("MovieSystem.BussinessLogic.MovieHandler");

    private MySqlMovieProxy m_movies;
    private MySqlActorProxy m_actors;
    private MySqlGenreProxy m_genres;

    public MovieHandler(MySqlUtilityManagment sql) {
        m_movies = new MySqlMovieProxy(sql);
        m_genres = new MySqlGenreProxy(sql);
        m_actors = new MySqlActorProxy(sql);
    }


    /**
     * add movie record to the DB and add records to movieActors table ad movieGenres table
     * @param m      movie to add to the DB
     * @throws DataAlreadyExistException
     */
    public void add(Movie m) throws DataAlreadyExistException {
        try {
            m_movies.addRecord(m);
            logger.info("Add movie " + m.getName()+" to dataBase was success");
        } catch (DataAlreadyExistException e) {
            logger.info("Movie "+m.getName()+" already exist in the DB");
            throw new DataAlreadyExistException(m.getName());
        }
    }

    /**
     * create the movie object and search for the right records in the B of actors and genres
     * @param name
     * @param director
     * @param year
     * @param length
     * @param country
     * @param genres
     * @param actors
     * @throws DataAlreadyExistException  -moive exists in the DB and will not be added
     */
    public synchronized void addNewMovie(String name,String director,String year,int length,String country,String genres,String actors) throws DataAlreadyExistException {
        Movie m = new Movie(name,director,year,length,country);
        StringTokenizer actorsTok = new StringTokenizer(actors,",");
        StringTokenizer genresTok = new StringTokenizer(genres,",");

 /*       while (actorsTok.hasMoreElements())
            m.addActor(m_actors.getRecord(actorsTok.nextToken()));
        while (genresTok.hasMoreElements())
            m.addGenre(m_genres.getRecord(genresTok.nextToken()));
 */
         String key="";
         while (actorsTok.hasMoreElements()){
             String actor;
             try {
                 actor = actorsTok.nextToken().trim();
                 key = String.valueOf(m_actors.getRecordByName(actor));
                 m.addActor(m_actors.getRecord(key));

             }
             catch (NoActorsException e) {                 
                 //actor is not asocciated to this movie  -
                 // could be because spelling mistake of name-->not found in the DB (actors table)                 
             }

         }

         key="";
         while (genresTok.hasMoreElements()){
             try {
                 key = String.valueOf(m_genres.getRecordByName(genresTok.nextToken()));
                 m.addGenre(m_genres.getRecord(key));

             }
             catch (NoGenresException e) {
                 //no genres asocciated to this movie
             }

         }
        
        add(m);
    }

    public void delete(Movie m) {
        if(m != null){
            logger.info("Delete movie " + m.getName()+" from dataBase");
            m_movies.deleteRecord(m.getName());
        }
        else{
            logger.error("Deleting a null movie. ignoring comnand.");
        }

    }

    public void delete(String movie){
        delete(get(movie));
    }

    public Movie get(String movieName){
        return m_movies.getRecord(movieName);
    }

    public boolean existMovie(String moviename) {
        return (m_movies.getRecord(moviename) != null);
    }

    public String[] searchMovie(String keyword, SearchMovieMethods method,int start,int amount){
        logger.info("Searching movies, filtered by "+method+"='"+keyword+"'");
        return m_movies.searchMovies(keyword,method,start,amount);
    }

    public String[] searchMovie(String keyword, SearchMovieMethods method,int start,int amount,String startWith){
        logger.info("Searching movies, filtered by "+method+"='"+keyword+"' starts with '"+startWith+"'");
        return m_movies.searchMovies(keyword,method,start,amount,startWith);
    }

    public Collection<Movie> getAllMovies() {
        return m_movies.searchRecords("all");
    }

	public String[] searchMovie(String keyword, String filter, int start, int amount) {
		logger.info("Searching movies, filtered by "+filter+"='"+keyword+"'");
        return m_movies.searchMovies(keyword,filter,start,amount);
	}
}